home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / TPBIND.ARJ / BIND.DOC next >
Text File  |  1991-05-22  |  12KB  |  437 lines

  1.  
  2.  
  3. Dear Turbo Pascal 6.0/Windows programmer,
  4.  
  5.  
  6.  
  7. Thank you for downloading the Loose Data Binder!  The
  8. Binder combines concepts from FlexList, OOP's generic
  9. container objects, and Borland's TurboVision/ObjectWindows
  10. TCollection object.
  11.  
  12.  
  13.  
  14. Adaptability
  15. ============
  16.  
  17. Think of the Loose Data Binder as a loose-leaf notebook.
  18. You can insert data into the LDB just like inserting pages
  19. into a notebook.  And of course you can just as easily take
  20. the data back out.  You can access the LDB as if it were a
  21. combination stack-queue-deque-list-array.  You can arrange
  22. your data in any order and even specify a compare function
  23. for sorting and/or searching.  The LDB expands or contracts
  24. automatically to accommodate varying numbers of nodes.  The
  25. CopyBinder, derived from Binder (LDB), gives the LDB the 
  26. ability to clone the data you want stored in a LDB on the
  27. fly.  It can also copy the data to/from the LDB nodes and 
  28. your variables.  Since a LDB is initialized at run time,
  29. the data it holds or even its creation can be specified at
  30. run time, thus allowing your applications new dimensions of
  31. adaptability to user inputs.
  32.  
  33.  
  34.  
  35. Getting Started
  36. ===============
  37.  
  38. Copy bind.pas to your compiler's standard source directory.
  39. Now for an example.  The compile and run LDB1.PAS.  Its
  40. contents are listed below.  It builds a LDB of cloned nodes
  41. and then displays them in several different ways.
  42.  
  43.  
  44.  
  45.     program ldb1;
  46.         uses bind;
  47.  
  48.         type strPtr = ^string;
  49.  
  50.     procedure display(D, M, A : pointer); far;
  51.         type strPtr = ^string;
  52.             intPtr = ^integer;
  53.         var i : integer;
  54.     begin
  55.         i := length(strPtr(D)^);
  56.  
  57.         inc(intPtr(A)^,i);
  58.                 writeln('length: ',i,
  59.                     '   accumulated: ',intPtr(A)^,
  60.                         '   string: ',strPtr(D)^);
  61.     end;
  62.  
  63.         function strcmp(D1, D2 : pointer) : integer; far;
  64.         begin
  65.             if (strPtr(D1)^ < strPtr(D2)^) then
  66.                     strcmp := -1
  67.                 else if (strPtr(D1)^ > strPtr(D2)^) then
  68.                     strcmp := 1
  69.                 else
  70.                     strcmp := 0
  71.         end;
  72.  
  73.  
  74.         const
  75.             s1 : string = 'Now is the time';
  76.                 s2 : string = 'for all programmers';
  77.                 s3 : string = 'to stop reinventing';
  78.                 s4 : string = 'the linked list!';
  79.  
  80.  
  81.         var B : CopyBinder;
  82.             i : word;
  83.  
  84.     begin
  85.         B.Init(CSTRING);
  86.  
  87.         B.pushC(@s1);
  88.         B.insqC(@s2);
  89.         B.atInsC(B.getNodes,@s3);
  90.         B.insqC(@s4);
  91.         
  92.         while (B.next) do
  93.             writeln(strPtr(B.current)^);
  94.  
  95.         writeln;
  96.  
  97.         for i := 0 to (B.getNodes - 1) do
  98.                     writeln(strPtr(B.atGet(i))^);
  99.  
  100.         writeln;
  101.  
  102.         i := 0;
  103.             
  104.         B.forEach(display,nil,@i);
  105.  
  106.         writeln;
  107.  
  108.  
  109.                 B.setCompare(strcmp);
  110.         B.sort;
  111.  
  112.         i := 0;
  113.         
  114.         B.forEach(display,nil,@i);
  115.  
  116.                 B.Done;
  117.  
  118.                 readln
  119.  
  120.         end.
  121.  
  122.  
  123. Notice that first the LDB is pushed like a stack.  Next it
  124. is queued, arrayed, and finally queued.  Next is used to
  125. walk across the binder.  Notice that stack, queue, and
  126. array primitives don't disturb the current node!
  127.  
  128.  
  129. The LDB also has built in iterators, much more powerful than
  130. TurboVision's TCollection.  The forEach iterator applies the
  131. given function against each element of the LDB and passes in
  132. what can be used as a mask and an accumulator.  I'm using
  133. the accumulator to sum the length of strings printed thus 
  134. far.
  135.  
  136. Next a compare function is specified for the LDB and a sort
  137. is performed.
  138.  
  139. The CopyBinder destructor calls Dfree() for each element
  140. when discarding the instance.  Please note that the Binder
  141. destructor does not, by default, which allows it to bind
  142. data variables in your program.  If you use the CopyBinder
  143. to bind non allocated data, besure to override its
  144. destructor so that it doesn't try to delete non-dynamic
  145. data!
  146.  
  147.  
  148.  
  149. Our next example can be found in ldb2.cpp.
  150.  
  151.  
  152.  
  153.     program ldb2;
  154.         uses bind;
  155.  
  156.         type strPtr = ^string;
  157.  
  158.  
  159.         const
  160.             s1 : string = 'Now is the time';
  161.                 s2 : string = 'for all programmers';
  162.                 s3 : string = 'to stop reinventing';
  163.                 s4 : string = 'the linked list';
  164.                 s5 : string = 'and container classes.';
  165.  
  166.  
  167.         function strcmp(D1, D2 : pointer) : integer; far;
  168.         begin
  169.             if (strPtr(D1)^ < strPtr(D2)^) then
  170.                     strcmp := -1
  171.                 else if (strPtr(D1)^ > strPtr(D2)^) then
  172.                     strcmp := 1
  173.                 else
  174.                     strcmp := 0
  175.         end;
  176.  
  177.  
  178.         var B : Binder;
  179.             i : word;
  180.  
  181.     begin
  182.         B.Init;
  183.                 B.setDelta(1);
  184.                 B.setLimit(3);
  185.                 B.setMaxNodes(3);
  186.  
  187.         B.push(@s1);
  188.         B.insq(@s2);
  189.         B.atIns(B.getNodes,@s3);
  190.         B.insq(@s4);
  191.                 B.insq(@s5);
  192.  
  193.         while (B.next) do
  194.             writeln(strPtr(B.current)^);
  195.  
  196.                 B.setComparE(strcmp);
  197.                 if (B.findFirst(@s3) <> BNOTFOUND) then
  198.             writeln(strPtr(B.current)^);
  199.  
  200.                 B.Done;
  201.  
  202.                 readln
  203.  
  204.         end.
  205.  
  206.  
  207. I've used the Binder class here, which only binds pointers
  208. to data.  The constructor is called, and then the LDB is
  209. restricted to having a maximum of three nodes.  The
  210. following relationship is always maintained in a LDB:
  211.  
  212.      1 <= delta <= limit <= maxNodes <= BMAXNODES
  213.  
  214. The last two fail which cause them to call the binder
  215. error function explaining there are no vacancies left.
  216.  
  217. Next the compare function is set and a search is performed.
  218. The LDB knows automatically that it isn't sorted so the 
  219. search is a linear one.  If it had been sorted than a
  220. binary search would have been used internally.  FindFirst
  221. set the current node and returns its index.
  222.  
  223. Remember the Binder destructor, by default, doesn't delete
  224. its member elements.
  225.  
  226.  
  227.  
  228. For our last example, let's revisit the CopyBinder class.
  229.  
  230. I didn't tell you before, but CopyBinder has two virtual
  231. functions, Dclone() and Dcopy(), that tells its other
  232. member functions how to clone and copy your data in the
  233. course of operations.  CSTRING is defined as 0, which tells
  234. these functions to treat the data as normal C strings.
  235. When cloning the data, the clone was only made as big as
  236. necessary to hold the string being warehoused.  If you
  237. give it another value, other than 0, then cloning and
  238. copying will be performed for data of this fixed size.
  239. If you have variant data, other than strings, or data with
  240. suballocated memory, than you can override these functions
  241. to handle your data accordingly.  Besure to override Dfree()
  242. as appropriate.  For this example, though, we'll use fixed
  243. sized data.
  244.  
  245. The following listing can be found in ldb3.cpp.
  246.  
  247.  
  248.  
  249.     program ldb3;
  250.         uses bind;
  251.  
  252.  
  253.     type
  254.  
  255.             YourRecPtr = ^YourRec;
  256.         YourRec = record
  257.             name : ^string;
  258.             end;
  259.  
  260.  
  261.     procedure display(D, M, A : pointer); far;
  262.     begin
  263.             writeln(YourRecPtr(D)^.name^)
  264.         end;
  265.  
  266.         const
  267.             s : string = 'Pat Programmer';
  268.  
  269.  
  270.         var
  271.             B : CopyBinder;
  272.                 R : YourRec;
  273.                 i : word;
  274.  
  275.     begin
  276.             B.Init(sizeof(YourRec));
  277.  
  278.  
  279.         R.name := @s;
  280.  
  281.         for i := 1  to 10 do
  282.             B.ins(@R);
  283.  
  284.         B.forEach(display,nil,nil);
  285.  
  286.         B.allDel;
  287.  
  288.                 B.Done;
  289.  
  290.                 readln
  291.  
  292.         end.
  293.  
  294.         
  295.  
  296.         
  297.  
  298.  
  299. Here the CopyBinder is constructed to clone and copy data
  300. that is sizeof(YourRec) bytes long.  As it turns out though,
  301. I don't call any cloning functions (they end in capital C
  302. for Clone/Copy).  Since CopyBinder is derived publicly from
  303. the Binder object the latter's functions are still available.
  304.  
  305. The forEach iterator is used to display the elements.
  306. Notice that B.allDel is called to discard all elements of
  307. the binder without disposing them before the destructor can
  308. get at them to dispose them.  Deleting nonallocated memory
  309. can be pretty serious business.  Don't do it!
  310.  
  311. This program brings up another point though.  It has simply
  312. inserted five pointers to the same record.  Even if I
  313. had called B.insC() instead there would have been five
  314. copies containing five pointers to the same name string:
  315. "Pat Programmer".  You must be sure to resolve double
  316. ownership problems.  Please note that if B.insC() had been
  317. called instead of calling B.ins() then B.allDel would
  318. have discarded the pointers to these five clones without
  319. disposing them!  Since Dfree(), Dclone(), Dcopy() are virtual,
  320. your can resolve any complexities inherent in your data
  321. types by overriding these functions.
  322.  
  323.  
  324.  
  325. Diving In
  326. =========
  327.  
  328. I've tried to give you a flavor for the LDB and keep the
  329. download file to a reasonable length.  Since you have the
  330. source code, study it, it's not too long.  And use the
  331. bind.pas interface section as a quite reference guide.
  332.  
  333.  
  334.  
  335. Small Code Sizes, Less Testing
  336. ==============================
  337.  
  338. Your applications can now have as many stacks, queues, 
  339. deques, lists, and/or elastic arrays without code size
  340. explosion.  That's because the LDB operates on any type of
  341. data, so new objects needn't be derived to accommodate new
  342. data types.  Laborious testing of a myriad of linked list
  343. primitives, especially for boundary condition faults, is
  344. thus avoided.
  345.  
  346.  
  347.  
  348. Coherent Flexible Design - Lower Investment
  349. ===========================================
  350.  
  351. It's no problem modifying your applications in midstream to
  352. incorporate various and differing list types, with the LDB
  353. no linked list code needs to be scrapped or rewritten.
  354. Investment in non reusable linked list code is essentially
  355. eliminated.  And with uniformity across applications and
  356. between Turbo Pascal and Turbo/Borland C++ versions, your
  357. software maintenance costs can be greatly reduced.
  358.  
  359.  
  360.  
  361. Less, Less, Less ...
  362. ====================
  363.  
  364. When you use LDB's for all your linked list needs, your
  365. applications will require:
  366.  
  367.   * less documentation
  368.     * less testing
  369.       * less code space
  370.         * less programming time
  371.       * less investment in non reusable code
  372.         * less software maintenance effort
  373.           * less cross application training
  374.           
  375.  
  376.  
  377. Get Popping - Register Today!
  378. =============================
  379.  
  380. Register bind.pas today and get your applications popping!
  381. This version of bind.pas is shareware meaning try before you
  382. buy.  It is provided for your convenience in evaluating the
  383. product to reach a buy/no buy decision.  For any other use
  384. you are required, by law, to register.  Registration, 
  385. provides you with a license to use bind.pas and its
  386. associated files in your applications without royality.
  387.  
  388.         TP  Loose Leaf Binder registration fee ... $15
  389.  
  390. Upon registration, you will be sent a DOS formatted diskette
  391. with the next version of the LDB tool, when  available.
  392. Please specify 3.5" or 5.25" diskette and the date of your
  393. current version!  If I receive 100 or more registrations,
  394. I will write a full length manual and put a ready to print
  395. copy on diskette.   Registrants are entitled to telephone
  396. support.
  397.  
  398. Make your check or money order payable to:
  399.  
  400.     PSW / Power SoftWare
  401.     P.O. Box 10072
  402.     McLean, VA 22102 - 8072
  403.     USA (703) 759-3838
  404.  
  405.  
  406.  
  407. Additional Versions
  408. ===================
  409.  
  410. Depending on demand, a version will be introduced for ANSI C.
  411. Please feel free to contact me with your comments or
  412. suggestions.  If you call, please don't call in the middle of
  413. the night or on Sundays!
  414.  
  415.  
  416.  
  417.  
  418. Background
  419. ==========
  420.  
  421.  
  422. I had a need to port FlexList to Microsoft Windows and other
  423. "after-thought" virtual memory systems and also to expand it
  424. into what I call a PolyMesh, polymorphic nodes belonging to
  425. more than one FlexList at the same time.
  426.  
  427. What you have downloaded here is a TP version incorporating
  428. the functionality of TCollect married to the functionality
  429. of FlexList.  The binder is not streamable here.  That code
  430. I extracted since most won't need it until their programs
  431. grow much more complex.
  432.  
  433. Thanks again!  John
  434.  
  435.  
  436.  
  437.